﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Newtonsoft.Json.Linq;
using System.Collections.Specialized;

namespace MTA.TripPlanner
{
    public enum ScheduleWeekDay
    {
        sun = 0, mon = 1, tue = 2, wed = 3, thr = 4, fri = 5, sat = 6
    }

    public class StopSchedule
    {
        public String Name { get; set; }
        public DateTime[] Times { get; set; }

        public StopSchedule(JObject obj)
        {
            Name = (String)obj["name"];
            Times = (from t in (JArray)obj["time"]
                     select DateTime.Parse((String)t)).ToArray();
        }

        public String Print()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Name: " + Name + "\r\n");
            foreach (DateTime d in Times)
                sb.Append(d.ToString("h:mm tt") + "\r\n");
            return sb.ToString();
        }
    }

    public class ScheduleOptions
    {
        private FeedUrlBuilder _params = new FeedUrlBuilder(ConfigurationManager.AppSettings["SchedulePage"]);
        public FeedUrlBuilder Params { get { return _params; } }

        public ScheduleWeekDay Day { set { _params["day"] = ((int)value).ToString(); } }
        public bool Leaving { set { _params["lvar"] = value == true ? "lv" : "ar"; } }
        public int Hour { set { _params["hour"] = value.ToString(); } }
        public int Min { set { _params["min"] = value.ToString(); } }
        public bool PM { set { _params["ampm"] = value == true ? "pm" : "am"; } }
        public bool NextTrip { set { _params["next"] = value == true ? "y" : String.Empty; } }
    }

    public class Schedule : BaseFeed<Schedule>
    {
        String _name = String.Empty;
        RouteDirection _direction = RouteDirection.NoInfo;
        public StopSchedule _on = null;
        public StopSchedule _off = null;


        public string RouteName { get { return _name; } }
        public RouteDirection Direction { get { return _direction; } }
        public StopSchedule Stop_On { get { return _on; } }
        public StopSchedule Stop_Off { get { return _off; } }

        public static string FeedUrl
        {
            get { return ConfigurationManager.AppSettings["SchedulePage"]; }
        }

        public static Schedule ConvertOne(JObject c)
        {
            return new Schedule()
            {
                _name = (string)c["route"],
                _direction = ((String)c["direction"]).GetRouteDirection(),
                _on = new StopSchedule((JObject)c["stop_on"]),
                _off = new StopSchedule((JObject)c["stop_off"])
            };
        }

        //        *  route_id = route id
        //The route id is an integer.
        //    * stop_on = stop_id
        //The origin point  is the boarding stop for the trip.
        //    * stop_off = stop_id
        //The destination point is the alighting stop for the trip.
        //    * day [optional] = sun | mon | tue | wed | thr | fri | sat
        //The day is the day of the week for the trip, not the date. The day is based on the time criteria value ('lv' or 'ar'). If the day is omitted, the day value is set to the current day.
        //    * lvar [optional] = lv | ar
        //This value will determine if the trip is designed around leaving or arriving by the trip time. If this value is omitted, it is automatically set to 'lv'.
        //    * hour [optional] = 1 - 12
        //This is an integer value between 1 and 12. Defaults to 'now' if omitted.
        //    * min [optional] = 0 - 59
        //This is an integer value between 0 and 59. Defaults to 'now' if omitted.
        //    * ampm [optional] = am | pm
        //Two character string: 'am', or 'pm'. Defaults to 'now' if omitted.
        //    * next [optional] = y
        //If set to 'y', then time fields are ignored and time is set to 'now'. Real-time adjustments are made to first time in the list when real-time data is available.



        public static List<Schedule> GetTrip(int routeid, int stop_on, int stop_off)
        {
            return GetTrip(routeid, stop_on, stop_off, null);
        }

        public static List<Schedule> GetTrip(int routeid, int stop_on, int stop_off, ScheduleOptions options)
        {
            JSONRequest request = new JSONRequest(FeedUrl);
            if (options != null)
                request.Params = options.Params;
            request.Params["route"] = routeid.ToString();
            request.Params["stop_on"] = stop_on.ToString();
            request.Params["stop_off"] = stop_off.ToString();

            return ConvertJSONArray(request,(o) => o["schedule"], ConvertOne, false);

        }

    }
}
